package br.com.passeionaweb.appengine.tabelafipe;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.passeionaweb.appengine.tabelafipe.data.Make;
import br.com.passeionaweb.appengine.tabelafipe.data.Model;
import br.com.passeionaweb.appengine.tabelafipe.data.PMF;
import br.com.passeionaweb.appengine.tabelafipe.data.Version;
import br.com.passeionaweb.appengine.tabelafipe.data.Year;
import br.com.passeionaweb.appengine.tabelafipe.data.YearVersion;

import com.google.appengine.repackaged.org.json.JSONArray;

@SuppressWarnings("serial")
public class GetJsonServlet extends HttpServlet {

	private final PersistenceManager pm = PMF.get().getPersistenceManager();

	private Make make;
	private Model model;
	private Year year;
	private Version version;

	@SuppressWarnings("unchecked")
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
			IOException {
		resp.setContentType("application/json");
		Map<String, String> paramMap = req.getParameterMap();
		String resultJson = "null";
		if (paramMap.containsKey(Make.KEY_MAKE)) {
			make = Make.getMake(Long.parseLong(req.getParameter(Make.KEY_MAKE)));
			if (paramMap.containsKey(Model.KEY_MODEL)) {
				model = pm.getObjectById(Model.class, Long.valueOf(req.getParameter(Model.KEY_MODEL)));
				if (paramMap.containsKey(Year.KEY_YEAR)) {
					year = ((List<Year>) pm.newQuery(
							Year.class,
							"WHERE " + Year.KEY_YEAR + " == '" + req.getParameter(Year.KEY_YEAR)
									+ "'").execute()).get(0);
					if (paramMap.containsKey(Version.KEY_VERSION)) {
						version = ((List<Version>) pm.newQuery(
								Version.class,
								"WHERE " + Version.KEY_VERSION + " == '"
										+ req.getParameter(Version.KEY_VERSION) + "'").execute())
								.get(0);
						// resultJson = getPriceJson();
					} else {
						resultJson = getVersionsJson();
					}
				} else {
					resultJson = getYearsJson();
				}
			} else {
				resultJson = getModelsJson();
			}
		} else {
			resultJson = getMakesJson();
		}
		resp.getWriter().write(resultJson);
	}

	private String getMakesJson() {
		String result = "";
		Query query = pm.newQuery(Make.class);
		query.setOrdering("make asc");
		try {
			List<Make> makes = (List<Make>) query.execute();
			if (!makes.isEmpty()) {
				JSONArray jsonarray = new JSONArray();
				for (Make make : makes) {
					Map<String, Object> jsonMap = new HashMap<String, Object>();
					jsonMap.put("id", make.getId());
					jsonMap.put("make", make.getMake());
					jsonarray.put(jsonMap);
				}
				result = jsonarray.toString();
			} else {
				result = "{error:\"no makes available\"}";
				// TODO update makes table
			}
		} finally {
			query.closeAll();
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	private String getModelsJson() {
		String result = "";
		if (make != null) {
			
			Query q = pm.newQuery(Model.class);
			q.setFilter("makeid == param_makeid");
			q.declareParameters("Long param_makeid");
			List<Model> models = (List<Model>) q.execute(make.getId());
			if (!models.isEmpty()) {
				JSONArray jsonarray = new JSONArray();
				for (Model model : models) {
					Map<String, Object> jsonMap = new HashMap<String, Object>();
					jsonMap.put("id", model.getId());
					jsonMap.put("model", model.getModel());
					jsonarray.put(jsonMap);
				}
				result = jsonarray.toString();
			}else {
				result = "{error:\"no models for this make\"}";
			}
		} else {
			result = "{error:\"make was not supplied\"}";
		}
		return result;
	}

	private String getYearsJson() {
		String result = "";
		if(make == null || model == null){
			result = "{'error':'make or model not provided'}";
		}else{
			 Query q = pm.newQuery(Version.class);
			 q.setFilter("modelid == param_modelid");
			 q.declareParameters("Long param_modelid");
			 List<Version> versions = (List<Version>)q.execute(model.getId());
			 List<Year> years = new ArrayList<Year>();
			 for(Version version : versions){
				 q = pm.newQuery(YearVersion.class);
				 q.setFilter("versionid == param_versionid");
				 q.declareParameters("Long param_versionid");
				 List<YearVersion> yvs = (List<YearVersion>) q.execute(version.getId());
				 for(YearVersion yv : yvs){
					 Year year = Year.getYear(yv.getYearid());
					 if(!years.contains(year)){
						 years.add(year);
					 }
				 }
			 }
			 
			 if(years.size()>0){
				 JSONArray jsonarray = new JSONArray();
				 for(Year year : years){
					 Map<String, Object> jsonMap = new HashMap<String, Object>();
						jsonMap.put("id", year.getId());
						jsonMap.put("year", year.getYear());
						jsonarray.put(jsonMap);
				 }
				 result = jsonarray.toString();
			 }else{
				 result = "{error:'no years available for this model'}";
			 }
		}
		return result;
	}

	private String getVersionsJson() {
		String result = "";
		
		return result;
	}

	private String getPriceJson() {
		/*
		 * String result = ""; Query query = pm.newQuery(Price.class);
		 * query.setOrdering("price asc");
		 * query.setFilter("versionid == param_id");
		 * query.declareParameters("String param_id"); try { List<Price> prices
		 * = (List<Price>) query.execute(version.getId()); if
		 * (!prices.isEmpty()) { JSONArray jsonarray = new JSONArray(); for
		 * (Price price : prices) { Map<String, Object> jsonMap = new
		 * HashMap<String, Object>(); jsonMap.put("_id", price.getId());
		 * jsonMap.put("price", price.getPrice()); jsonarray.put(jsonMap); }
		 * result = jsonarray.toString(); } else { result =
		 * "{error:\"no prices available\"}"; } } finally { query.closeAll(); }
		 */
		return "";// result;
	}
}
